home *** CD-ROM | disk | FTP | other *** search
- /*
- File: UnitTableDriveQSupport.c
-
- Contains: xxx put contents here xxx
-
- Version: xxx put version here xxx
-
- Copyright: © 2000 by Apple Computer, Inc., all rights reserved.
-
- */
-
- /*
- File: UnitTableDriveQSupport.c
-
- Contains: All functionality for managing Drive Queue elements.
-
- Version: 1.0
-
- Copyright: © 1998-2000 by Apple Computer, Inc., all rights reserved.
-
-
- */
- #include <DriverGestalt.h>
- #include <Gestalt.h>
- #include <Files.h>
- #include <LowMem.h>
- #include <SCSI.h> // For Block 0 and some partition map definitions.
-
- #include "UnitTableFunctions.h"
- #include "UnitTableFloppySupport.h"
- #include "UnitTableDriveQSupport.h"
- #include "UnitTableDeviceAccess.h"
- #include "UnitTableDriverIcons.h"
- #include "UnitTableReadWriteSupport.h"
-
- // pmPartStatus field flags
- // Old versions from ATA and SCSI - should be deprecated
- // but need to be supported since they are used by Drive Setup.
- enum
- {
- kPMapDriveSetupSig = 'DSU1',
- STAT_WRITABLE = 0x20,
- STAT_MOUNT = 0x40000000,
- STAT_STARTUP = 0x80000000
- };
-
- // New fields that will definitely be added to SCSI.h (should add the AUX fields also)
- enum
- {
- // Drive Setup doesn't play nicely with others or these values
- /* kPartitionHFSIsWriteProtected = 0x00000100,*/
- /* kPartitionHFSDoNotAutomount = 0x00000200,*/
- /* kPartitionHFSIsStartup = 0x00000400, // This may not be needed for new drivers*/
- /**/
- /* kPartitionHFSStatusBitsMask = 0x0000FF00*/
- kPartitionHFSIsWriteProtected = 0x00010000,
- kPartitionHFSDoNotAutomount = 0x00020000,
- kPartitionHFSIsStartup = 0x00040000, // This may not be needed for new drivers
-
- kPartitionHFSStatusBitsMask = 0x00FF0000
- };
-
- enum
- {
- kInstallStartState = 1,
- kInstallPartitionReadDoneState,
- kInstallReadNextPartBlock,
- kInstallProcessNextPartBlock
- };
-
- typedef struct InstallPB
- {
- volatile OSStatus status;
- void *ourCompletion;
- UInt32 capacity;
- UInt32 blockSize;
- OSType currentMediaType;
- UInt8 currentState;
- UInt32 currentPartBlock;
- UInt32 lastPartBlock;
- DriveInstallCompletionProcPtr installCompletion;
- Boolean useNativeBlocks;
- UInt8 buffer[2048];
- };
-
- typedef struct InstallPB InstallPB, *InstallPBPtr;
-
- #define kNumberOfDriveRecords 12
-
- static InstallPB theInstallPB;
- static DriveQRec theDriveQRecArray[kNumberOfDriveRecords];
- static DriverRefNum gOurDrvrRefNum;
- static TimerID gPostEventTimer = 0;
- static UInt16 gCurrentDriverMode = kDriverModeNormal;
- static Boolean gDoPostEvents = true;
-
- static void ResetDriveQueue( DriveQRecPtr drive);
- static DriveQRecPtr FindPermanentDriveQRec( void );
-
- static DriveQRecPtr CreateDriveQRecForPartition( UInt32 partitionID, UInt32 partitionSize, UInt32 partitionOffset );
-
- static void ScanMediaForPartitions( UInt32 userData, OSStatus status );
-
- static Boolean ShouldPartitionBeMounted( Partition* thePartition );
-
- static void EjectDrive(DriveQRecPtr theDrivePtr);
- static OSStatus PostTheDiskInsertEvents( void );
- static OSStatus RetryPostEventInterrupt( void *p1, void *p2);
-
- // This may be removed
- static Boolean IsVolumeMountedForDrive(UInt16 driveNum);
-
- #pragma mark --
- #pragma mark Driver Mode routines
- static UInt32 gModeUserData;
- static UInt16 ReadOnlyMediaDriveNum = 0;
- static ControlStatusCompletionProcPtr gModeCompletionProc;
-
- static void StartNormalModeCompletion(Boolean wasSuccessful);
-
- OSStatus DriveQueueControlCallSupport( UInt32 userData,
- CntrlParamPtr cntrlPBPtr,
- ControlStatusCompletionProcPtr callBack )
- {
- OSStatus err = noErr;
- SInt16 driveNum;
-
- gModeUserData = userData;
- gModeCompletionProc = callBack;
-
- driveNum = cntrlPBPtr->ioVRefNum;
-
- // Parse the control codes…
- switch( cntrlPBPtr->csCode )
- {
- case kcsSetDriverMode: // Change the driver's operating mode
- {
- UInt16 newMode = cntrlPBPtr->csParam[0];
- DriveQRecPtr driveQPtr;
- Boolean volumeMounted = false;
-
- if ( newMode == gCurrentDriverMode )
- {
- // The new mode is the same as the current mode, do nothing
- // and return noErr
- err = noErr;
- break;
- }
-
- driveQPtr = GetFirstDriveQRec();
- while ( driveQPtr != nil )
- {
- // Check each drive owned by the driver for mounted volumes
- if ( IsVolumeMountedForDrive ( driveQPtr->driveNum ) == true )
- {
- // There are still volumes mounted for the drive, this prevents
- // the driver from changing modes.
- volumeMounted = true;
- break;
- }
-
- driveQPtr = GetNextDriveQRec( driveQPtr );
- }
-
- if (volumeMounted == true )
- {
- err = paramErr;
- break;
- }
-
- if ( newMode == kDriverModeNormal )
- {
- gCurrentDriverMode = newMode;
- if ( cntrlPBPtr->csParam[1] != 0 )
- {
- gDoPostEvents = false;
- }
-
- EjectDrive( FindPermanentDriveQRec());
- InstallDrive( &StartNormalModeCompletion );
- err = kRequestPending;
- }
- else if ( newMode == kDriverModeUtility )
- {
- // Set mode to utility
- gCurrentDriverMode = newMode;
-
- // Do an eject on all drive Q elements to remove from the queue
- driveQPtr = GetFirstDriveQRec();
- while ( driveQPtr != nil )
- {
- if ( driveQPtr != FindPermanentDriveQRec())
- {
- EjectDrive( driveQPtr );
- }
-
- driveQPtr = GetNextDriveQRec( driveQPtr );
- }
-
- // Update the permanent to represent the entire media
- FindPermanentDriveQRec()->partoffset = FindPermanentDriveQRec()->curoffset = 0;
- UpdateQ(FindPermanentDriveQRec()->driveNum, FindPermanentDriveQRec()->capacity);
- err = noErr;
- }
- else
- {
- err = paramErr;
- }
- }
- break;
-
- case kcsManageReadOnlyMediaQueue:
- {
- UInt16 newMode = cntrlPBPtr->csParam[0];
- DriveQRecPtr driveQPtr;
-
- if ( newMode == kReadOnlyMediaQueueInstall )
- {
- // Install a Write protected Drive queue element to represent the entire media
- // and return the DriveNum in csParam[1]
- if ( GetNumberOfVolumes() == 0 )
- {
- // There are no mounted volumes, and so probably no media in the\
- // drive. Return a paramErr.
- err = paramErr;
- break;
- }
-
- driveQPtr = CreateNewDriveQRecForPartition( NextPartitionID(), 0, 0 );
- if ( driveQPtr )
- {
- driveQPtr->isWriteProtected = true;
-
- UpdateQ(driveQPtr->driveNum, driveQPtr->capacity);
- ReadOnlyMediaDriveNum = cntrlPBPtr->csParam[1] = driveQPtr->driveNum;
- err = noErr;
- }
- else
- {
- err = controlErr;
- }
- }
- else if ( newMode == kReadOnlyMediaQueueRemove )
- {
- // If there is a Read Only Media drive queue installed, remove it now
-
- // Make sure that the passed in drive does not have a mounted volume.
- if ( IsVolumeMountedForDrive ( ReadOnlyMediaDriveNum ) == true )
- {
- // There are still volumes mounted for the drive, this means that
- // this is not the Read Only queue. Return paramErr.
- err = paramErr;
- break;
- }
-
- driveQPtr = FindDriveQRecForDriveNum( ReadOnlyMediaDriveNum );
- if ( driveQPtr != nil )
- {
- RemoveDrive(driveQPtr);
- err = noErr;
- }
- else
- {
- err = paramErr;
- }
-
- ReadOnlyMediaDriveNum = 0;
- }
- else
- {
- // The function passed in is not defined, return a paramErr.
- err = paramErr;
- }
- }
- break;
-
- default:
- {
- err = controlErr;
- }
- break;
- }
-
- return err;
- }
-
- void StartNormalModeCompletion(Boolean wasSuccessful)
- {
- OSStatus err;
-
- gDoPostEvents = true;
- if ( wasSuccessful == true )
- {
- err = noErr;
- }
- else
- {
- err = ioErr;
- }
-
- (*gModeCompletionProc) (gModeUserData, err);
- }
-
- OSStatus DriveQueueStatusCallSupport( UInt32 userData,
- CntrlParamPtr cntrlPBPtr,
- ControlStatusCompletionProcPtr callBack )
- {
- OSStatus err = noErr;
- SInt16 driveNum;
-
- gModeUserData = userData;
- gModeCompletionProc = callBack;
-
- driveNum = cntrlPBPtr->ioVRefNum;
-
- // Parse the control codes…
- switch(cntrlPBPtr->csCode)
- {
- case kcsGetDriverMode:
- {
- cntrlPBPtr->csParam[0] = gCurrentDriverMode;
- if ( gCurrentDriverMode == kDriverModeUtility )
- {
- // This is the get mode info call for Utility mode,
- // return the drive number representing the whole disk.
- cntrlPBPtr->csParam[1] = FindPermanentDriveQRec()->driveNum;
- }
-
- err = noErr;
- }
- break;
-
- case kcsManageReadOnlyMediaQueue:
- {
- if ( ReadOnlyMediaDriveNum == 0 )
- {
- err = paramErr;
- break;
- }
-
- cntrlPBPtr->csParam[0] = ReadOnlyMediaDriveNum;
- err = noErr;
- }
- break;
-
- default:
- {
- err = statusErr;
- }
- break;
- }
-
- return err;
- }
-
-
- #pragma mark --
- #pragma mark Drive Information Query Functions
- Boolean IsDriveNumberValid( UInt16 driveNum )
- {
- DriveQRecPtr theDriveQRec;
-
- theDriveQRec = FindDriveQRecForDriveNum( driveNum );
- if ( theDriveQRec != nil )
- {
- return true;
- }
-
- return false;
- }
-
- Boolean IsDriveNumWriteProtected( UInt16 driveNum )
- {
- DriveQRecPtr theDriveQRec;
-
- if( IsDriveAFloppy( driveNum ) == true )
- {
- theDriveQRec = GetFloppyDriveRec();
- }
- else
- {
- theDriveQRec = FindDriveQRecForDriveNum( driveNum );
- }
-
- if ( theDriveQRec != nil )
- {
- return theDriveQRec->isWriteProtected;
- }
-
- return false;
- }
-
- Boolean AreThereMountedDrives( void )
- {
- int loopCount;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if ( theDriveQRecArray[loopCount].isValidRecord == true )
- {
- return true;
- }
- }
-
- return false;
- }
-
- UInt32 GetNumberOfVolumes( void )
- {
- int loopCount;
- UInt32 volCount = 0;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if ( theDriveQRecArray[loopCount].isValidRecord == true )
- {
- volCount++;
- }
- }
-
- return volCount;
- }
-
- OSType GetMediaTypeForDriveNum( UInt16 driveNum )
- {
- DriveQRecPtr drive = nil; // pointer to our volume record structure
-
- drive = FindDriveQRecForDriveNum( driveNum );
- return drive->deviceType;
- }
-
- void GetMediaIconForDriveNum( UInt16 driveNum, DiskIcon *iconPtr )
- {
- DriveQRecPtr drive = nil; // pointer to our volume record structure
-
- drive = FindDriveQRecForDriveNum( driveNum );
- BlockMoveData(drive->mediaIconPtr, iconPtr, sizeof(DiskIcon));
- }
-
- void GetDriveStatusForDriveNum( UInt16 driveNum, DrvSts *statusPtr )
- {
- DriveQRecPtr drive = nil; // pointer to our volume record structure
-
- drive = FindDriveQRecForDriveNum( driveNum );
- BlockMoveData(&drive->driveStatus, statusPtr, sizeof(DrvSts));
- }
-
- #pragma mark --
- #pragma mark Drive Queue Management Functions
- // This is to workaround a bug in the PowerPC native version of the AddDrive
- // call in systems before 8.5, where one needs to be added to the desired
- // drive number before calling AddDrive.
- void NativeAddDrive(DriverRefNum drvrRefNum, UInt16 driveNumber, DrvQElPtr drvQEl)
- {
- UInt32 gestaltResponse;
- OSStatus gestaltErr;
-
- // Check System version to see if we need to add one to AddDrive calls
- gestaltErr = Gestalt(gestaltSystemVersion,(long *) &gestaltResponse);
-
- // If this is boot time, the system version will be reported as 0x0000.
- // If we are booting, we must be on a system greater than 8.5, so we do not need the fix
- if( (gestaltErr == noErr) && (( (gestaltResponse&0xFFFF) < 0x0850 ) && ((gestaltResponse&0xFFFF) != 0x0000 )))
- {
- // We are on a system before 8.5, we need to add 1 to AddDrive calls
- driveNumber += 1;
- }
-
- AddDrive( drvrRefNum, driveNumber, drvQEl);
- }
-
- void ResetDriveQueue( DriveQRecPtr drive)
- {
- if(drive->isFloppy == true)
- {
- ResetFloppyDriveQueue( drive );
- }
- else
- {
- drive->driveStatus.track = 0; // Not used on non floppies
- drive->driveStatus.writeProt = 0; // not write protected yet
- drive->driveStatus.diskInPlace = 0; // Ejectable Disk
- drive->driveStatus.installed = 1; // drive is installed
- drive->driveStatus.sides = 0; // Not used on non floppy disks
- drive->driveStatus.qType = 1; // both dQDrvSz and dQDrvSz2 are used
- drive->driveStatus.dQFSID = 0; // File Manager's volume type
- drive->driveStatus.driveSize = 0; // volume size in blocks
- drive->driveStatus.driveS1 = 0;
- }
- }
-
- static Boolean driveQueueIsInstalled = false;
-
- OSStatus InstallDriveQueueElement( DriverRefNum theDrvrRefNum )
- {
- OSStatus err = noErr;
- int loopCount;
- DriveQRecPtr theDriveQPtr = nil;
- DriverGestaltSupportedMediaTypesResponse *supportedTypes;
-
- gOurDrvrRefNum = theDrvrRefNum;
-
- if(IsDeviceAccessEnabled() == false )
- {
- return kDeviceAccessNotAvailable;
- }
-
- if ( driveQueueIsInstalled == true )
- {
- return noErr;
- }
-
- driveQueueIsInstalled = true;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- BlockZero( &theDriveQRecArray[loopCount], sizeof( DriveQRec ));
- theDriveQRecArray[loopCount].isValidRecord = false;
- }
-
- supportedTypes = GetSupportedMediaTypesPtr();
-
- for ( loopCount = 0; loopCount < supportedTypes->supportTypesCount; loopCount++)
- {
- if ( supportedTypes->supportedTypesArray[loopCount] == kdgFloppyType )
- {
- err = SetupFloppyStructures( theDrvrRefNum );
- }
- else
- {
- theDriveQPtr = GetNewDriveQRec();
- ResetDriveQueue( theDriveQPtr );
- theDriveQPtr->deviceType = supportedTypes->supportedTypesArray[loopCount];
- theDriveQPtr->driveNum = NextQDrive(); // assign a logical drive number
- theDriveQPtr->isPermanentQElement = true;
- NativeAddDrive(theDrvrRefNum, theDriveQPtr->driveNum,(DrvQElPtr) &theDriveQPtr->driveStatus.qLink);
- }
- }
-
- if ( theDriveQPtr != nil )
- {
- // Wait until after the floppy queue is added to clear this field
- // This prevents floppy from getting the same drive queue element on devices
- // that support both floppy and non-floppy removables
- theDriveQPtr->isValidRecord = false;
- }
-
- return err;
- }
-
- OSStatus RemoveDriveQueueElement( void )
- {
- DriveQRecPtr theDriveQRec;
-
- if( gPostEventTimer != nil )
- {
- AbsoluteTime timeLeft;
-
- // Cancel any pending timers, we don't care what the
- // returned status is.
- (void) CancelTimer( gPostEventTimer, &timeLeft);
- gPostEventTimer = 0;
- }
-
- driveQueueIsInstalled = false;
-
- theDriveQRec = GetFirstDriveQRec(); // first volume of the drive
- while (theDriveQRec)
- {
- EjectDrive( theDriveQRec );
- theDriveQRec = GetNextDriveQRec( theDriveQRec ); // point to the next volume
- }
-
- // if we installed a fixed/removable drive queue, remove it.
- theDriveQRec = FindPermanentDriveQRec();
-
- if ( theDriveQRec != nil )
- {
- RemoveDrive( theDriveQRec );
- }
-
- RemoveFloppyStructures();
-
- return noErr;
- }
-
- void EjectDriveNum( UInt16 driveNum )
- {
- DriveQRecPtr theDriveQRec;
-
- theDriveQRec = FindDriveQRecForDriveNum( driveNum );
- if ( theDriveQRec != nil )
- {
- EjectDrive( theDriveQRec );
- }
- }
-
- // DriveQRec management functions
- DriveQRecPtr GetNewDriveQRec( void )
- {
- int loopCount;
- DriveQRecPtr permRec;
-
- permRec = FindPermanentDriveQRec();
-
- if ( permRec != nil )
- {
- if ( permRec->isValidRecord == false )
- {
- permRec->isValidRecord = true;
- return permRec;
- }
- }
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if (( theDriveQRecArray[loopCount].isValidRecord == false ) && ( theDriveQRecArray[loopCount].isFloppy == false ))
- {
- theDriveQRecArray[loopCount].isValidRecord = true;
- return &theDriveQRecArray[loopCount];
- }
- }
-
- return nil;
- }
-
- void FreeDriveQRec( DriveQRecPtr theDriveRecPtr )
- {
- if ( theDriveRecPtr!=nil )
- {
- if ( theDriveRecPtr->isFloppy == true )
- {
- ResetFloppyDriveQueue(theDriveRecPtr);
- theDriveRecPtr->isValidRecord = false;
- }
- else if ( theDriveRecPtr->isPermanentQElement == true )
- {
- ResetDriveQueue(theDriveRecPtr);
- theDriveRecPtr->isValidRecord = false;
- }
- else
- {
- BlockZero( theDriveRecPtr, sizeof( DriveQRec ));
- theDriveRecPtr->isValidRecord = false; // this is actually done by blockZero, repeated for emphasis
- }
- }
- }
-
- DriveQRecPtr FindDriveQRecForDriveNum( UInt16 driveNum )
- {
- int loopCount;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if (( theDriveQRecArray[loopCount].driveNum == driveNum ) && ( theDriveQRecArray[loopCount].isValidRecord == true ))
- {
- return &theDriveQRecArray[loopCount];
- }
-
- if (( theDriveQRecArray[loopCount].driveNum == driveNum ) && ( theDriveQRecArray[loopCount].isPermanentQElement == true ))
- {
- return &theDriveQRecArray[loopCount];
- }
- }
-
- return nil;
- }
-
- DriveQRecPtr FindDriveQRecForPartitionNum( UInt32 partNum )
- {
- int loopCount;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if (( theDriveQRecArray[loopCount].partitionNo == partNum ) && ( theDriveQRecArray[loopCount].isValidRecord == true ))
- {
- return &theDriveQRecArray[loopCount];
- }
- }
-
- return nil;
- }
-
- DriveQRecPtr FindPermanentDriveQRec( void )
- {
- int loopCount;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if (( theDriveQRecArray[loopCount].isPermanentQElement == true ) && ( theDriveQRecArray[loopCount].isFloppy == false ))
- {
- return &theDriveQRecArray[loopCount];
- }
- }
-
- return nil;
- }
-
- DriveQRecPtr GetFirstDriveQRec( void )
- {
- int loopCount;
-
- for ( loopCount = 0; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if ( theDriveQRecArray[loopCount].isValidRecord == true )
- {
- return &theDriveQRecArray[loopCount];
- }
- }
-
- return nil;
- }
-
- DriveQRecPtr GetNextDriveQRec( DriveQRecPtr theDriveQRec )
- {
- int loopCount;
- int inDriveQNum;
-
- for ( inDriveQNum = 0; inDriveQNum < kNumberOfDriveRecords; inDriveQNum++)
- {
- if ( &theDriveQRecArray[inDriveQNum] == theDriveQRec )
- {
- break;
- }
- }
-
- if ( inDriveQNum < kNumberOfDriveRecords )
- {
- for ( loopCount = inDriveQNum; loopCount < kNumberOfDriveRecords; loopCount++)
- {
- if ((loopCount != inDriveQNum) && ( theDriveQRecArray[loopCount].isValidRecord == true ))
- {
- return &theDriveQRecArray[loopCount];
- }
- }
- }
-
- return nil;
- }
-
- //------------------------------------------------------------------------------
- // Function: CreateDriveQRecForPartition
- //
- // Description: This function creates a volume record for the specified drive.
- // The volume is appended to the drive's volume queue and a logical
- // logical drive is installed in the system drive queue.
- //
- // Input: drive: pointer to the drive record of the volume to create
- // partitionID: the volume's partition ID
- // volSize: size of the volume in blocks
- // volOffset: block offset of volume on drive
- //
- // Output: Returns nil pointer if fails, else pointer to volume record
- //
- // NOTE: Assumes all inputs are valid!
- //-------------------------------------------------------------------------------
- DriveQRecPtr CreateDriveQRecForPartition( UInt32 partitionID, UInt32 partitionSize, UInt32 partitionOffset )
- {
- DriveQRecPtr driveRec;
- UInt32 currentCapacity, currentBlockSize;
- Boolean isWriteProtected;
- OSType currentType;
-
- GetMediaProperties( ¤tCapacity, ¤tBlockSize, &isWriteProtected, ¤tType);
-
- if ( currentType == kdgFloppyType )
- {
- driveRec = GetFloppyDriveRec();
- }
- else
- {
- // Search for a DriveQRec record for the partition to be created…
- driveRec = FindDriveQRecForPartitionNum( partitionID );
- }
-
- if ( driveRec != nil ) // if record exists for this partition…
- {
- if (driveRec->driveStatus.diskInPlace) // if partition is already online…
- { // we shouldn't be here - fall thru
- return nil;
- }
- }
- else // need to create DriveQRec
- {
- driveRec = GetNewDriveQRec(); // Allocate storage for record
- }
-
- if (driveRec) // If a DriveQRec was created.
- {
-
- driveRec->isValidRecord = true;
-
- driveRec->isWriteProtected = isWriteProtected;
-
- if( driveRec->isWriteProtected == true)
- {
- driveRec->driveStatus.writeProt = 0x80; // disk is write protected
- }
- else
- {
- driveRec->driveStatus.writeProt = 0; // not write protected yet
- }
-
- if ( currentType == kdgDiskType )
- {
- // This disk is non-ejectable
- driveRec->driveStatus.diskInPlace = 0x48; // Non-Ejectable Disk, but we want eject calls
- }
- else
- {
- // This is a removable disk
- driveRec->driveStatus.diskInPlace = 1; // Ejectable Disk
- }
-
- driveRec->driveStatus.installed = 1; // drive is installed
- driveRec->driveStatus.dQFSID = 0; // File Manager's volume type
-
- if( driveRec->isFloppy == false)
- {
- driveRec->driveStatus.qType = 1; // both dQDrvSz and dQDrvSz2 are used
- driveRec->driveStatus.driveSize = (UInt16) partitionSize; // partition size in blocks
- driveRec->driveStatus.driveS1 = (UInt16) (partitionSize >> 16);
- }
-
- driveRec->mountPartition = false; // don't mount this volume,
- driveRec->diskInsertPosted = false; // it's not mounted yet,
- driveRec->partitionNo = partitionID; // save the partition ID
-
- // Save volume's block offset and set its access mode by setting curoffset to the
- // same (access is relative to partition offset if curoffset is non-zero, else physical)
- driveRec->curoffset = partitionOffset; // block offset of partition
- driveRec->partoffset = partitionOffset; // partition offset
- driveRec->partblks = partitionSize; // save size for our use also
- driveRec->blockSize = currentBlockSize;
- if ( currentBlockSize == kFileSystemRequestBlockSize )
- {
- // Blocksize is the same as the file system default
- driveRec->capacity = currentCapacity;
- }
- else
- {
- // Blocksize is not the same as the file system default,
- // modify the capcity to reflect the number of file system blocks
- driveRec->capacity = currentCapacity * ( currentBlockSize / kFileSystemRequestBlockSize );
- }
-
- // Save the media type in the DriveQRec
- driveRec->deviceType = currentType;
-
- driveRec->mediaIconPtr = (Ptr) GetOneBitIconPtr( driveRec->deviceType );
- }
-
- return(driveRec);
- }
-
-
- //------------------------------------------------------------------------------
- // Function: ScanMediaForPartitions
- // Description: Searches for partitions on the media and installs them as
- // volumes for the associated drive. Assumes the drive does
- // not have any volumes installed yet.
- //
- // Input: theDrive: pointer to drive record
- // mountVols: true means to mount the drive's partitions
- //
- //-------------------------------------------------------------------------------
- void ScanMediaForPartitions( UInt32 userData, OSStatus status )
- {
- Boolean timetoMountThePartitions = false;
- InstallPBPtr installPBPtr;
- Boolean weHaveAFloppy = false;
-
- installPBPtr = (InstallPBPtr) userData;
- installPBPtr->status = status;
-
- switch(installPBPtr->currentState)
- {
- case kInstallStartState:
- {
- if ( theInstallPB.currentMediaType == kdgFloppyType )
- {
- // If we have a floppy disk, no need to scan for partitions
- // go ahead and mount the whole disk as a volume.
- // This also allows for unformatted media to be formatted.
- weHaveAFloppy = true;
- timetoMountThePartitions = true;
- break;
- }
-
- installPBPtr->currentState = kInstallPartitionReadDoneState;
-
- // Read block 0
- installPBPtr->status = DoReadWritePhysicalBlocks ( (UInt32) installPBPtr, 0, 1, installPBPtr->blockSize, true,
- (Ptr) installPBPtr->buffer, (kFileSystemRequestBlockSize), false, &ScanMediaForPartitions );
- }
- break;
-
- case kInstallPartitionReadDoneState:
- {
- UInt8 *buf = (UInt8 *) &installPBPtr->buffer; // Share 512 byte storage with PMap
- Boolean checkMacPartitions = true;
-
- if (installPBPtr->status == noErr)
- {
- Block0 *blkZero;
-
- blkZero = (Block0 *) buf;
-
- // Check for Macintosh partitions if Block0 has the correct signature.
- checkMacPartitions = ( blkZero->sbSig == sbSIGWord );
-
- // ----- PC-Exchange DOS format bug fix ------
- // PCX does not erase the partition map (blocks 1-31) when reformatting HFS to
- // DOS so we may still find a partition map. Check for DOS signature in block 0,
- // and if there, the Macintosh partition map is invalid.
- // check for Macintosh partitions if not a DOS signature
- /* checkMacPartitions = !(buf[kDOSSigLow] == kDOSSigValLo && buf[kDOSSigHi] == kDOSSigValHi);*/
- }
- else
- {
- // An error occurred on the read, return back a failure to the client
- installPBPtr->status = ioErr;
- break;
- }
-
- if (checkMacPartitions == false) // we don't need to check for Macintosh parititions…
- {
- timetoMountThePartitions = true; // we found a DOS signature, try to mount as DOS
- break;
- }
-
- installPBPtr->lastPartBlock = 1; // assume no partition map will be found
- installPBPtr->currentPartBlock = 1;
-
- } // no break, we want to execute next case
-
- case kInstallReadNextPartBlock:
- {
- if ( installPBPtr->currentPartBlock <= installPBPtr->lastPartBlock )
- {
- UInt32 blockSizeForRead;
- Boolean convertToSystemBlocks;
-
- if ( installPBPtr->useNativeBlocks == true )
- {
- blockSizeForRead = installPBPtr->blockSize;
- convertToSystemBlocks = false;
- }
- else
- {
- blockSizeForRead = kFileSystemRequestBlockSize;
- convertToSystemBlocks = true;
- }
-
- // Read a block from the media…
- installPBPtr->currentState = kInstallProcessNextPartBlock;
- installPBPtr->status = DoReadWritePhysicalBlocks ( (UInt32) installPBPtr, installPBPtr->currentPartBlock, 1, installPBPtr->blockSize, convertToSystemBlocks,
- (Ptr) installPBPtr->buffer, blockSizeForRead, false, &ScanMediaForPartitions );
- }
- else
- {
- timetoMountThePartitions = true; // we have finished scanning the partition map, mount what we have found
- }
- }
- break;
-
- case kInstallProcessNextPartBlock:
- {
- Partition *PartMap = (Partition *) &installPBPtr->buffer;
- Boolean mountPartition;
-
- if ( installPBPtr->status != noErr )
- {
- installPBPtr->currentPartBlock += 1;
- installPBPtr->currentState = kInstallReadNextPartBlock;
- ScanMediaForPartitions( (UInt32) installPBPtr, noErr );
- return;
- }
-
- // Verify we read a partition map entry…
- if (PartMap->pmSig != newPMSigWord) // Partition map signature?
- {
- if (( installPBPtr->currentPartBlock == 1 ) && ( installPBPtr->blockSize != kFileSystemRequestBlockSize ))
- {
- // If there is not a valid Partition Map signature and the
- // drive has blocks other than the standard 512 byte blocks,
- // the partition map may be written on native blocks.
- installPBPtr->useNativeBlocks = true;
- }
- else
- {
- installPBPtr->currentPartBlock += 1;
- }
-
- installPBPtr->currentState = kInstallReadNextPartBlock;
- ScanMediaForPartitions( (UInt32) installPBPtr, noErr );
- return;
- }
-
- if (installPBPtr->lastPartBlock == 1) // Readjust the number of map blocks
- installPBPtr->lastPartBlock = PartMap->pmMapBlkCnt;
-
- // Determine the partition type and do what is needed…
- mountPartition = ShouldPartitionBeMounted( PartMap );
- if ( mountPartition == true )
- {
- DriveQRecPtr newDriveRec;
- UInt32 blockCnt;
- UInt8 blockMultiplier = 1;
-
- // LaCie hard drive fix
- if ( PartMap->pmDataCnt == 0)
- {
- blockCnt = PartMap->pmPartBlkCnt;
- }
- else
- {
- blockCnt = PartMap->pmDataCnt;
- }
-
- if ( installPBPtr->useNativeBlocks == true )
- {
- blockMultiplier = (installPBPtr->blockSize)/kFileSystemRequestBlockSize;
- }
-
- // A valid paritition found! Create a DriveQRec for it.
- newDriveRec = CreateDriveQRecForPartition( installPBPtr->currentPartBlock * blockMultiplier, blockCnt * blockMultiplier,
- ( PartMap->pmPyPartStart * blockMultiplier) + ( PartMap->pmLgDataStart * blockMultiplier) );
-
- if ( newDriveRec == nil ) // If we failed, try the next partition
- {
- break;
- }
-
- // Save this partition's map entry number (remember to subtract 1 since the partition map starts on block 1)
- newDriveRec->partMapEntryNum = installPBPtr->currentPartBlock-1;
-
- // Determine if the old or new bits should be used
- if ( *((UInt32 *) &PartMap->pmPad[0x50]) == kPMapDriveSetupSig )
- {
- // This Partition Map has the DriveSetup signature, check the old bits
- // Check if the partition is software write protected.
- if ((PartMap->pmPartStatus & STAT_WRITABLE) == STAT_WRITABLE)
- {
- // Only change the value in the drive queue element if it is write protected since if the media
- // is hardware write protected, the locked flag in the drive queue element will already reflect this.
- newDriveRec->writeProtectedPart = false;
- }
- else
- {
- // This partition is not marked as writeable so the locked flag in the
- // drive queue needs to be set so that the OS won't try to write.
- newDriveRec->writeProtectedPart = true;
- newDriveRec->driveStatus.writeProt = 0x80;
- }
-
- if (( PartMap->pmPartStatus & STAT_MOUNT ) == STAT_MOUNT)
- {
- // This partition should be mounted, set the flag so we will post a disk insert event
- newDriveRec->mountPartition = true;
- }
- else
- {
- // Since we do not support the Drive Setup call to mount partitions,
- // for now, we will just remove the DriveQRec from the list.
- FreeDriveQRec( newDriveRec );
- }
- }
- else
- {
- // Check if the partition is software write protected.
- if ((PartMap->pmPartStatus & kPartitionHFSIsWriteProtected) == kPartitionHFSIsWriteProtected)
- {
- // This partition is not marked as writeable so the locked flag in the
- // drive queue needs to be set so that the OS won't try to write.
- newDriveRec->writeProtectedPart = true;
- newDriveRec->driveStatus.writeProt = 0x80;
- }
- else
- {
- // Only change the value in the drive queue element if it is write protected since if the media
- // is hardware write protected, the locked flag in the drive queue element will already reflect this.
- newDriveRec->writeProtectedPart = false;
- }
-
- if (( PartMap->pmPartStatus & kPartitionHFSDoNotAutomount ) != kPartitionHFSDoNotAutomount)
- {
- // This partition should be mounted, set the flag so we will post a disk insert event
- newDriveRec->mountPartition = true;
- }
- else
- {
- // Since we do not support the Drive Setup call to mount partitions,
- // for now, we will just remove the DriveQRec from the list.
- FreeDriveQRec( newDriveRec );
- }
- }
-
- /* if ((PartMap->pmPartStatus & kPartitionHFSIsStartup) == kPartitionHFSIsStartup) // is this flagged as the boot partition?*/
- /* {*/
- /* newDriveRec->startupPartition = true;*/
- /* }*/
- /* else*/
- /* {*/
- /* newDriveRec->startupPartition = false;*/
- /* }*/
- }
-
- // Go to next Partition
- installPBPtr->currentPartBlock += 1;
- installPBPtr->currentState = kInstallReadNextPartBlock;
-
- ScanMediaForPartitions( (UInt32) installPBPtr, installPBPtr->status );
- return;
- }
- break;
- }
-
- if ( timetoMountThePartitions == true )
- {
- DriveQRecPtr theDriveQRec;
-
- // If no partitions were found from the search above we assume the following:
- // 1. A Macintosh partition map exists, but it has either no file system partitions
- // or no partitions which we recognize (either or which is unlikely).
- // 2. The media has a Macintosh floppy format (HFS with no partition map)
- // 3. The media has a foreign format (DOS, etc.).
- //
- // In all cases we create a volume of the entire media capacity, post a disk inserted
- // event and let the File System Manager try and figure it out. Note we post a disk
- // inserted event rather than notifying FSM so if the media is not recognized (because
- // it's unformatted or the correct file system is not installed) the system will prompt
- // with a "This is not a Macintosh disk…" message. If we call FSM instead, the user will
- // not be prompted when the media is unformatted. This provides a way to format media
- // and also allows us to eject PCMCIA drives which have no volumes (no icons on desktop).
-
- if ( GetNumberOfVolumes() == 0) // if no partitions were found…
- {
- // Create a volume of entire media capacity with partitionID of 1
- if ( installPBPtr->blockSize == kFileSystemRequestBlockSize)
- {
- theDriveQRec = CreateDriveQRecForPartition( 1, installPBPtr->capacity, 0 );
- }
- else
- {
- UInt32 FSBlocksPerDeviceBlocks;
-
- FSBlocksPerDeviceBlocks = installPBPtr->blockSize/kFileSystemRequestBlockSize;
-
- theDriveQRec = CreateDriveQRecForPartition( 1, (installPBPtr->capacity * FSBlocksPerDeviceBlocks), 0 );
- }
-
- if(theDriveQRec)
- {
- theDriveQRec->mountPartition = true; // post disk inserted event later
- }
- }
-
- // DriveQRecs have been created for all partitions, now install them into the Drive Queue and
- // let them system know about them by posting Disk Insert events.
- if ( weHaveAFloppy == true )
- {
- if (theDriveQRec->mountPartition == true) // Do not do Add Drive for partitions not to be mounted
- {
- theDriveQRec->inDriveQ = true; // mark this entry as having been added to the drive Q.
- }
- }
- else
- {
- // Add the remaining volumes to the drive queue…
- theDriveQRec = GetFirstDriveQRec(); // first DriveQRec
- while (theDriveQRec)
- {
- if (theDriveQRec->mountPartition == true) // Do not do Add Drive for partitions not to be mounted
- {
- if (theDriveQRec == FindPermanentDriveQRec())
- {
- //theDriveQRec->driveNum = (FindPermanentDriveQRec())->driveNum; // assign a logical drive number
- }
- else
- {
- theDriveQRec->driveNum = NextQDrive(); // assign a logical drive number
- NativeAddDrive(gOurDrvrRefNum, theDriveQRec->driveNum, (DrvQElPtr) &theDriveQRec->driveStatus.qLink);
- }
-
- theDriveQRec->inDriveQ = true; // mark this entry as having been added to the drive Q.
- }
-
- theDriveQRec = GetNextDriveQRec( theDriveQRec ); // point to the next volume
- }
- }
-
- if ( GetNumberOfVolumes() != 0 )
- {
- OSErr theErr;
-
- theErr = PostTheDiskInsertEvents();
- if(theErr != noErr)
- {
- // For some reason, the disk could not be mounted,
- // We should eject and let the user decide whether to try again.
- (*installPBPtr->installCompletion)( false );
- return;
- }
- }
- else // Abort if no volumes installed for drive
- {
- (*installPBPtr->installCompletion)( false );
- return;
- }
-
- (*installPBPtr->installCompletion)( true );
- return;
- }
-
- if ((installPBPtr->status != 1 ) && (installPBPtr->status != noErr))
- {
- (*installPBPtr->installCompletion)( false );
- }
- }
-
- DriveQRecPtr CreateNewDriveQRecForPartition( UInt32 partitionID, UInt32 partitionSize, UInt32 partitionOffset )
- {
- DriveQRecPtr driveRec = nil; // pointer to our volume record structure
-
- driveRec = CreateDriveQRecForPartition( partitionID, partitionSize, partitionOffset );
- if ( driveRec )
- {
- driveRec->driveNum = NextQDrive(); // assign a logical drive number
- NativeAddDrive( gOurDrvrRefNum, driveRec->driveNum,(DrvQElPtr) &driveRec->driveStatus.qLink);
- driveRec->inDriveQ = true;
-
- return driveRec;
- }
-
- return driveRec;
- }
-
- //------------------------------------------------------------------------------
- // Function: InstallDrive
- //
- // Description: Installs a physical drive and its volumes under the driver's
- // control. The driver determines if the drive is one it can
- // manage, and if so, creates and initializes the drive's record,
- // sets the drives operating mode and options, and mounts its
- // partitions to the system.
- //
- //-------------------------------------------------------------------------------
- void InstallDrive( DriveInstallCompletionProcPtr completionProc )
- {
- //..............................................................................
- // Search for file system partitions on the media and install them as volumes
- // of this drive. If no volumes, the drive must be considered unusable.
- UInt32 currentCapacity, currentBlockSize;
- Boolean isWriteProtected;
- OSType currentType;
-
- GetMediaProperties( ¤tCapacity, ¤tBlockSize, &isWriteProtected, ¤tType );
-
- BlockZero((Ptr) &theInstallPB, sizeof(InstallPB));
- theInstallPB.capacity = currentCapacity;
- theInstallPB.blockSize = currentBlockSize;
- theInstallPB.currentMediaType = currentType;
- theInstallPB.installCompletion = completionProc;
- theInstallPB.useNativeBlocks = false;
- theInstallPB.currentState = kInstallStartState;
- ScanMediaForPartitions( (UInt32) &theInstallPB, noErr );
- }
-
-
- //------------------------------------------------------------------------------
- // Function: EjectDrive
- // Description: Removes a physical drive and its volumes from our control
- //
- //-------------------------------------------------------------------------------
- void EjectDrive(DriveQRecPtr theDrivePtr)
- {
- if (theDrivePtr) // If the drive exists…
- {
- if( theDrivePtr->isPermanentQElement == false )
- {
- Dequeue((QElemPtr) &(theDrivePtr->driveStatus.qLink), GetDrvQHdr()); // remove from drive queue
- }
-
- FreeDriveQRec( theDrivePtr );
- }
- }
-
- //------------------------------------------------------------------------------
- // Function: RemoveDrive
- // Description: This is used to remove any Drive Queue element
- // this includes our permanent queue element.
- //
- //-------------------------------------------------------------------------------
- void RemoveDrive(DriveQRecPtr theDrivePtr)
- {
- if (theDrivePtr) // If the drive exists…
- {
- Dequeue((QElemPtr) &(theDrivePtr->driveStatus.qLink), GetDrvQHdr()); // remove from drive queue
- }
-
- FreeDriveQRec( theDrivePtr );
- }
-
- //------------------------------------------------------------------------------
- // Function: IsDriveQueue1Free()
- //
- // Description: Returns true if drive queue element one is not in use,
- // and returns false if it is.
- //
- // Input: none
- //
- // Output: Boolean
- //-------------------------------------------------------------------------------
- Boolean IsDriveQueueNumberFree( UInt16 driveNum )
- {
- QHdrPtr qhdr = GetDrvQHdr(); // Pointer to Drive Queue
- DrvQEl *qel = (DrvQEl*) (qhdr->qHead); // Pointer to first element
-
- while (qel) // While not end of queue,
- {
- if (qel->dQDrive == driveNum) // check to see if drive number is in use
- {
- return false; // drive number is in use, stop looking
- }
- else // else next queue element
- {
- qel = (DrvQEl*) (qel->qLink);
- }
- }
-
- return true; // if we got here, drive number is free
- }
-
- //------------------------------------------------------------------------------
- // Function: NextQDrive
- //
- // Description: Returns the next unused logical drive number from the system
- // Drive Queue. The Drive Queue is searched starting with a
- // logical drive number 8.
- //
- // Input: none
- //
- // Output: The highest Drive Queue drive number + 1
- //-------------------------------------------------------------------------------
- SInt16 NextQDrive( void )
- {
- QHdrPtr qhdr = GetDrvQHdr(); // Pointer to Drive Queue
- DrvQEl *qel = (DrvQEl*) (qhdr->qHead); // Pointer to first element
- SInt16 drv = 8; // Start above built in drives
-
- while (qel) // While not end of queue,
- {
- if (qel->dQDrive == drv) // if drive number used,
- {
- drv++; // bump number, and
- qel = (DrvQEl*) (qhdr->qHead); // search from start
- }
- else // else next queue element
- {
- qel = (DrvQEl*) (qel->qLink);
- }
- }
-
- return drv; // Return the next logical drive
- }
-
- //------------------------------------------------------------------------------
- // Function: UpdateQ
- // Description: Updates the specified drive in the system drive queue with
- // the specified capacity
- //
- // Input: qDrive: the drive to update
- // newSize: the new drive capacity
- //-------------------------------------------------------------------------------
- void UpdateQ(SInt16 qDrive, SInt32 newSize)
- {
- DriveQRecPtr theDriveQ;
-
- theDriveQ = FindDriveQRecForDriveNum( qDrive );
- if ( theDriveQ != nil )
- {
- DrvQEl *qel;
-
- qel = (DrvQEl *) &(theDriveQ->driveStatus.qLink);
- qel->dQDrvSz2 = newSize>>16; // new capacity (hi word)
- qel->dQDrvSz = newSize; // low word of capacity
- theDriveQ->partblks = newSize; // save size for our use also
- }
- }
-
- //------------------------------------------------------------------------------
- // FUNCTION: NextPartitionID
- // PURPOSE: Returns the next unique partition ID for all volumes associated
- // with the specified drive. NOTE: This function should be used only
- // when adding volumes which do not have a partition map on the media.
- //
- // INPUT: drive: pointer to the drive record to search for next partition ID
- //
- // OUTPUT: a unique partition ID related to the specified volume
- //
- //-------------------------------------------------------------------------------
- SInt32 NextPartitionID( void )
- {
- DriveQRecPtr driveQ = nil;
- SInt32 nextPartitionID = 1; // Start search with partition ID of 1
-
- driveQ = GetFirstDriveQRec(); // first DriveQRec pointer
-
- while (driveQ) // while not end of DriveQRec queue…
- {
- if (driveQ->partitionNo == nextPartitionID) // if partition ID used
- {
- nextPartitionID++; // bump partition ID
- driveQ = GetFirstDriveQRec(); // reset DriveQRec pointer
- }
- else
- {
- driveQ = GetNextDriveQRec( driveQ ); // otherwise, point to next DriveQRec
- }
- }
-
- return nextPartitionID; // return number of next partition
- }
-
- //------------------------------------------------------------------------------
- // Function: PostTheDiskInsertEvents
- // Description: Post Disk Insert event for all partitions to be mounted
- //
- // Input: none
- //
- // Output: Returns any errors that occur from PostEvent
- //-------------------------------------------------------------------------------
- OSStatus PostTheDiskInsertEvents( void )
- {
- DriveQRecPtr driveRec;
- OSStatus mountErr = noErr;
-
- // Post a Disk Inserted event for all HFS partitions not yet mounted
- driveRec = GetFirstDriveQRec(); // first DriveQRec structure
-
- while (driveRec) // for all partitions on drive…
- {
- if ((driveRec->driveStatus.diskInPlace != 0) && // if media in place,
- (driveRec->mountPartition) && // and partition should be mounted,
- (!driveRec->diskInsertPosted)) // and hasn't been done yet
- {
- // This DriveQRec is marked as mountable, check if
- // PostEvents are turned on and if so issue one for this DriveQRec.
- if ( gDoPostEvents == true )
- {
- mountErr = PostEvent(diskEvt, driveRec->driveNum);
- }
- else
- {
- // PostEvents are turned off, return noErr because
- // the application that turned the PostEvents off
- // should handle mounting the appropriate drives.
- mountErr = noErr;
- }
-
- if ( mountErr == noErr )
- {
- driveRec->diskInsertPosted = true;
- }
- }
-
- driveRec = GetNextDriveQRec( driveRec ); // next DriveQRec pointer
- }
-
- if ( mountErr != noErr )
- {
- // We should only get an error to PostEvent on boot,
- // Set our timer try again
- AbsoluteTime theWait;
-
- theWait = DurationToAbsolute(durationSecond * 60);
- theWait = AddAbsoluteToAbsolute(UpTime(), theWait);
- mountErr = SetInterruptTimer( &theWait, &RetryPostEventInterrupt, nil, &gPostEventTimer);
- }
-
- return mountErr; // return error if one occurred
- }
-
- OSStatus RetryPostEventInterrupt( void *p1, void *p2)
- {
- #pragma unused ( p1, p2 )
- gPostEventTimer = 0;
-
- (void) PostTheDiskInsertEvents();
- return noErr;
- }
-
- #pragma mark --
- #pragma mark Volume Related Routines
- //------------------------------------------------------------------------------
- // Function: IsVolumeMountedForDrive
- // Description: Searches the volume queue for a mounted volume specified
- // by vRefNum. If one is found, true is returned.
- //
- // Input: driveNum: the volume reference to search for
- //
- // Output: true if volume mounted, else false
- //-------------------------------------------------------------------------------
- Boolean IsVolumeMountedForDrive( UInt16 driveNum )
- {
- QHdrPtr volQ = LMGetVCBQHdr(); // VCB queue head pointer
- VCBPtr theVol; // first VCB
-
- if ( volQ == nil )
- {
- theVol = nil;
- }
- else
- {
- theVol = (VCBPtr) volQ->qHead;
- }
-
- while( theVol != nil )
- {
- // The test for whether a volume is mounted or not is done using
- // the VCB fields vcbDrvNum and vcbDRefNum. A volume is mounted
- // only if it is online.
- //
- // online offline ejected
- //
- // vcbDrvNum >0 (DrvNum) 0 0
- // vcbDRefNum <0 (DRefNum) <0 (-DrvNum) >0 (DrvNum)
-
- if (theVol->vcbDrvNum == driveNum) // if volume specified is online…
- {
- return true; // volume is mounted
- }
-
- theVol = (VCBPtr) theVol->qLink; // next VCBPtr
- }
-
- // There is no volume mounted for the requested driveNum.
- return false;
- }
-
- #pragma mark --
- #pragma mark Partition Format Related Routines
- //------------------------------------------------------------------------------
- // Function: ConvertToUC
- // Description: Converts the input ASCII character to its upper if possible.
- // Character range is a…z
- //
- // Input: theCharacter: character to be converted
- // Output: the upper case of the character if possible, else the character
- //-------------------------------------------------------------------------------
- static UInt8 ConvertToUC(UInt8 theCharacter);
-
- UInt8 ConvertToUC(UInt8 theCharacter)
- {
- if ((theCharacter >= 'a') && (theCharacter <= 'z')) // a lower case character?
- return(theCharacter & 0xDF); // if so, convert to upper case
- else
- return(theCharacter); // if not, return as is
- }
-
- //------------------------------------------------------------------------------
- // Function: GetPartitionType
- // Description: This function determines the partition type. Following parti-
- // tion types are recognized:
- // • Apple driver partition
- // • HFS partition
- // • Apple partition map, Apple Free, and Apple Scratch
- // If an unknown type is detected, the function returns ISADDTOQUEUE
- // file system ID to be handled by someone else above.
- //
- // Input: A pointer to a partition: pm *
- //
- // Output: Returns true if this partion should be mounted
- //
- //-------------------------------------------------------------------------------
- Boolean ShouldPartitionBeMounted(Partition* thePartition )
- {
- SInt16 i,j;
- static char *knownPartitionTypes[] = {
- "APPLE_DRIVER43",
- "APPLE_HFS",
- "APPLE_PARTITION_MAP",
- "APPLE_FREE",
- "APPLE_SCRATCH",
- "APPLE_PRODOS",
- "APPLE_DRIVER_ATA",
- "APPLE_PATCHES",
- "APPLE_UNIX_SVR2"
- };
-
- // The following defines refer to the items in knownPartitionTypes.
- #define POS_BEGIN 0
- #define POS_APPLE_DRIVER 0
- #define POS_APPLE_HFS 1
- #define POS_APPLE_PRODOS 5
- #define POS_APPLE_ATADRIVER 6
- #define POS_END 8
-
- // First check to see if we recognize one of the known partitions.
- for (j = POS_BEGIN; j <= POS_END; j++)
- {
- char *knownPartitionTypePtr;
-
- i = 0;
- knownPartitionTypePtr = knownPartitionTypes[j];
- while (knownPartitionTypePtr[i] == ConvertToUC (thePartition->pmParType[i]))
- {
- if (knownPartitionTypePtr[i++] == '\0') // We found one that we recognize.
- {
- switch(j)
- {
- case POS_APPLE_HFS:
- case POS_APPLE_PRODOS:
- {
- return true;
- }
- break;
-
- default:
- {
- // We must have found one of the ones that can't be mounted.
- return false;
- }
- break;
- }
- }
- }
- }
-
- // None matched. Now see if we shouldn't add this to the queue.
- return false;
- }
-